package edu.chen.dao.impl;

import edu.chen.bean.User;
import edu.chen.dao.UserDao;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 在注入sessionFactory之后获取Session有两个方法：
 *      1、sessionFactory.openSession    每次都会打开一个新的Session,并且需要手动关闭
 *      2、sessionFactory.getCurrentSession  是从当前上下文中获取的Session,多次获取同一个session
 *              第一次调用是会创建一个Session并且绑定在本线程,在事务提交或者回滚的时候会自动关闭
 *         开启该功能的方法在Hibernate的配置文件中(hibernate.cfg.xml),
 *                 <property name="hibernate.current_session_context_class">org.springframework.orm.hibernate5.SpringSessionContext</property>
 *                 中间值为Thread的时候需要通过HibernateUtil来获取SessionFactory在获取线程绑定的Session
 *         SessionFactory的所有操作必须在事务中完成所以一般需要配置事务,applicationContext.xml
 */


//持久层Bean声明注解
@Repository("userDaoImplByHibernate")
/**
 * 事务注解
 * 使用前需要在applicationContext.xml中开启事务注解<tx:annotation-driver/>
 * 该注解只能被应用到public可见度的方法上,在private和protected和package-visible的方法上时不会报错,但不会被配置为事务
 * 在接口上使用@Transactional的时候,只有在设置基于接口的代理时才生效。（JDK自带基于接口的动态代理）
 * 在注解的属性中可以用RollbackFor或者noRollbackFor指定
 * 默认为RuntimeException回滚 其他可查异常(checked exceptions)不会回滚
 * rollbackFor = Exception.class 可以使可查异常回滚
 * 另外在属性中还能配置事务的读写属性,传播规则,隔离性
 */
@Transactional
public class UserDaoImplByHibernate implements UserDao {

    private SessionFactory sessionFactory;

    /**
     * 以set形式注入SessionFactory
     * @param sessionFactory
     */
    //自动装配注解
    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public void insert(User user) {
        sessionFactory.getCurrentSession().save(user);
    }

    public void delete(String username) {
        Session session = sessionFactory.getCurrentSession();
        session.delete(query(username));
    }

    public User query(String username) {
        Query query = sessionFactory.getCurrentSession().createQuery("from User u where u.username = ?").setParameter(0,username);
        //获得的userList 基0
       List<User> userList = query.list();
       if(userList.size() == 0){
           return null;
       }
       return userList.get(0);
    }

}
